package com.gwq.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gwq.base.ResponseData;
import com.gwq.entity.SysRole;
import com.gwq.entity.SysRoleMenu;
import com.gwq.entity.SysUser;
import com.gwq.entity.SysUserRole;
import com.gwq.param.RoleParam;
import com.gwq.utils.DateUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  角色管理
 * </p>
 *
 * @author gwq
 * @since 2022-06-07
 */
@Api(description = "角色管理")
@RestController
@RequestMapping("/sys/role")
public class SysRoleController extends BaseController {

    @ApiOperation(value="获取角色相关联的菜单id")
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAnyAuthority('sys:role:list')")
    public ResponseData info(@PathVariable("id") String id){
        SysRole sysRole = sysRoleService.getById(id);

        // 获取角色相关联的菜单id
        List<SysRoleMenu> role_id = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
        List<String> collect = role_id.stream().map(p -> p.getMenuId()).collect(Collectors.toList());
        sysRole.setMenuIds(collect);

        return ResponseData.success(sysRole);
    }

    @ApiOperation(value="角色分页查询")
    @GetMapping("/list")
    @PreAuthorize("hasAnyAuthority('sys:role:list')")
    public ResponseData list(RoleParam roleParam){
        Page<SysRole> pageData = (Page<SysRole>) sysRoleService.page( new Page<>(roleParam.getPage(),roleParam.getSize()),
                new QueryWrapper<SysRole>().like(StrUtil.isNotBlank(roleParam.getName()), "name", roleParam.getName()).orderByDesc("created_at"));
        return ResponseData.success(pageData);
    }

    @ApiOperation(value="角色新增")
    @PostMapping("/save")
    @PreAuthorize("hasAnyAuthority('sys:role:save')")
    @Transactional
    public ResponseData save(@Validated @RequestBody SysRole sysRole, Principal principal){
        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        if(sysUser!=null) {
            sysRole.setCreatedBy(sysUser.getId());
            sysRole.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
        }
        SysRole sysRole1 = sysRoleService.getByCode(sysRole.getCode());
        if(sysRole1!=null){
            return ResponseData.fail("编码不能重复!");
        }
        sysRoleService.save(sysRole);

        return ResponseData.success(sysRole);
    }

    @ApiOperation(value="角色修改")
    @PostMapping("/update")
    @PreAuthorize("hasAnyAuthority('sys:role:update')")
    @Transactional
    public ResponseData info(@Validated @RequestBody SysRole sysRole, Principal principal){

        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        if(sysUser!=null) {
            sysRole.setUpdatedBy(sysUser.getId());
            sysRole.setUpdatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
        }

        sysRoleService.updateById(sysRole);

        // 更新缓存
        sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());

        return ResponseData.success(sysRole);
    }

    @ApiOperation(value="角色删除")
    @PostMapping("/delete")
    @PreAuthorize("hasAnyAuthority('sys:role:delete')")
    @Transactional
    public ResponseData info(@RequestBody List<String> roleIds){
        sysRoleService.removeByIds(roleIds);
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id", roleIds));
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id", roleIds));
        // 缓存同步删除
        roleIds.stream().forEach(id -> {
            sysUserService.clearUserAuthorityInfoByRoleId(id);
        });

        return ResponseData.success(true);
    }

    @ApiOperation(value="分配权限")
    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAnyAuthority('sys:role:perm')")
    @Transactional
    public ResponseData info(@PathVariable("roleId") String roleId, @RequestBody List<String> menuIds){
        ArrayList<SysRoleMenu> sysRoleMenus = new ArrayList<>();
        menuIds.stream().forEach(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);
            sysRoleMenus.add(roleMenu);
        });
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        sysRoleMenuService.saveBatch(sysRoleMenus);
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        return ResponseData.success(menuIds);
    }

}
